﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SHARED
{
    public class MasterElement : ICloneable, IComparable, IEquatable<MasterElement>
    {
        public List<Element> elements = new List<Element>();
        public int level = 0;
        public int occurences = 0;
        public string searchType = string.Empty;
        private List<MasterElement> children = new List<MasterElement>();
        private MasterElement parent = null;

        public MasterElement(List<Element> elements)
        {
            this.elements = elements;
            occurences = 1;
        }
        public MasterElement()
        {
            elements = new List<Element>();
            occurences = 1;
        }
        public MasterElement(int level)
        {
            elements = new List<Element>();
            this.level = level;
            occurences = 1;
        }

        public void AddElement(Element el)
        {
            elements.Add(el);
        }

        public MasterElement Root
        {
            get
            {
                MasterElement masterElement = this;
                while (masterElement.parent != null)
                {
                    masterElement = masterElement.parent;
                }
                return masterElement;
            }
        }
        public MasterElement Parent
        {
            get { return parent; }
            set
            {
                if (value == parent)
                {
                    return;
                }
                if (value != null && parent != null)
                {
                    parent.children.Remove(this);
                }
                if (value != null && !value.children.Contains(this))
                {
                    value.children.Add(this);
                }
                parent = value;
            }
        }

        public void AddChild(MasterElement c)
        {
            if (!this.children.Contains(c))
            {
                children.Add(c);
            }
        }

        public List<MasterElement> Children
        {
            get { return children; }
            set { children = value; }
        }

        public Element GetElement(string tagName)
        {
            for (int i = 0; i < elements.Count; i++)
            {
                if (elements[i].tagName.ToLower().Trim() == tagName.ToLower().Trim())
                {
                    return elements[i];
                }
            }
            return null;
        }
        public object Clone()
        {
            MasterElement newMasterElement = new MasterElement(level);
            for (int i = 0; i < elements.Count; i++)
            {
                Element tempel = new Element();
                tempel.tagName = elements[i].tagName;
                tempel.isTagOnly = elements[i].isTagOnly;
                tempel.tableName = elements[i].tableName;
                tempel.tagType = elements[i].tagType;
                tempel.columnSize = elements[i].columnSize;
                tempel.baseColumnName = elements[i].baseColumnName;
                newMasterElement.AddElement(tempel);

            }
            return newMasterElement;
        }

        public int CompareTo(object obj)
        {
            try
            {

                for (int i = 0; i < this.elements.Count; i++)
                {
                    for (int j = 0; j < ((MasterElement)obj).elements.Count; j++)
                    {
                        if (!this.elements[i].isTagOnly && !((MasterElement)obj).elements[j].isTagOnly &&
                                                    this.elements[i].tagName.ToLower().Trim() == ((MasterElement)obj).elements[j].tagName.ToLower().Trim())
                        {
                            if (this.elements[i].tagValue != ((MasterElement)obj).elements[j].tagName)
                            {
                                return -1;
                            }
                        }
                    }
                }
                return 0;
            }
            catch
            {
                throw;
            }
        }

        public bool Equals(MasterElement other)
        {
            try
            {
                if (this.elements.Count != other.elements.Count)
                {
                    return false;
                }

                for (int i = 0; i < other.elements.Count; i++)
                {

                    if (!this.elements.Contains(other.elements[i]))
                    {
                        return false;
                    }
                }
                return true;
            }
            catch
            {
                throw;
            }
        }
    }
}
